#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>

#include "qworker.h"
#include "con_command.h"
#include "log.h"

qworker g_worker;

qworker::qworker():
	network_(NULL),
	sqlhandler_(NULL),
	exit_(false)
{
}

void qworker::init_worker(controllers_network *_network, sqlhandle *_sqlhandler)
{
	network_ = _network;
	sqlhandler_ = _sqlhandler;
}

void qworker::run()
{
	assert((network_ != NULL) && (sqlhandler_ != NULL));

	const int short_delay = 1;
	const int long_delay = 5;
	const int no_delay = 0;

	int delay = short_delay;

    while (!exit_)
    {
    	int command = 0;
    	con_state::controller_id c_id = 0;
    	int param = 0;

    	if (sqlhandler_->get_queue_cmd(command, c_id, param))
    	{
    		delay = no_delay;

    		switch (command)
    		{
    			case CONTROLLER_GSM_TU:
    			{
    				try
    				{
    					network_->set_connection_command_by_id(c_id, new set_status_command(*network_, *sqlhandler_, c_id,  param));
    				}
    				catch (std::exception &e)
    				{
    				}
    			}
    			break;

    			case CONTROLLER_START_PROG_NUM:
    			{
    				try
    				{
    					network_->set_connection_command_by_id(c_id, new set_program_command(*network_, *sqlhandler_, c_id,  param));
    				}
    				catch (std::exception &e)
    				{
    				}
    			}
    			break;

    			case CONTROLLER_SYNC_TIME:
    			{
    				try
    				{
    					network_->set_connection_command_by_id(c_id, new sync_time_command(*network_, *sqlhandler_, c_id));
    				}
    				catch (std::exception &e)
    				{
    				}
    			}
    			break;

    			case CONTROLLER_WRITE_PROG:
    			{
    				try
    				{
    					con_load_command *command = new con_load_command(*network_, *sqlhandler_, c_id);

    					if (command)
    					{
    						if (command->init_prog())
    						{
    	 						network_->set_connection_command_by_id(c_id, command);
    						}
    						else
    						{
    							delete command;
    						}
    	   				}
    				}
    				catch (std::exception &e)
    				{
    				}
    			}
    			break;

    		}
    	}
    	else
    	{
    		if (delay == no_delay)
    		{
    			delay = short_delay;
    		}
    		else
    		{
    			boost::xtime xt;
    			boost::xtime_get(&xt, boost::TIME_UTC);
    			xt.sec += delay;

    			boost::thread::sleep(xt);

    			if (delay == short_delay)
    			{
    				delay = long_delay;
    			}
    		}
    	}
    }	
}
	
void qworker::stop()
{
    exit_ = true;
}

